﻿using CefSharp.DevTools.CSS;
using LightCAD.Core;
using LightCAD.Core.Elements;
using LightCAD.Drawing.Actions;
using LightCAD.MathLib;
using LightCAD.Runtime;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LightCAD.UI.Axis
{
    public partial class AxisManageFrom : FormBase, IAxisLineManageFrom
    {
        private DataTable dataTable;
        private string path = Path.Combine(System.IO.Path.GetTempPath(), "axisGridDrawData.json");
        public AxisManageFrom()
        {
            InitializeComponent();


        }

        private AxisGridAction axisLineAction;

        public AxisManageFrom(params object[] args) : this()
        {
            if (args != null && args.Length > 0)
            {
                this.axisLineAction = (AxisGridAction)args[0];
            }
        }

        private void AxisManageFrom_Load(object sender, EventArgs e)
        {
            axisLineDrawDataGroupByDirs = new Dictionary<DrawDirection, AxisLineDrawDataCollection>();
            axisLineDrawDataGroupByDirs.Add(DrawDirection.Top, new AxisLineDrawDataCollection());
            axisLineDrawDataGroupByDirs.Add(DrawDirection.Left, new AxisLineDrawDataCollection());
            axisLineDrawDataGroupByDirs.Add(DrawDirection.Bottom, new AxisLineDrawDataCollection());
            axisLineDrawDataGroupByDirs.Add(DrawDirection.Right, new AxisLineDrawDataCollection());
            axisLineDrawDataGroupByDirs.Add(DrawDirection.Angle, new AxisLineDrawDataCollection());
            axisLineDrawDataGroupByDirs.Add(DrawDirection.depth, new AxisLineDrawDataCollection());
            dataTable = new DataTable();

            //初始化DataTable，并将datatable绑定到DataGridView的数据源
            DataColumn c0 = new DataColumn("Id", typeof(string));
            DataColumn c1 = new DataColumn("Spacing", typeof(string));
            DataColumn c2 = new DataColumn("Length", typeof(string));
            DataColumn c3 = new DataColumn("Count", typeof(string));
            dataTable.Columns.Add(c0);
            dataTable.Columns.Add(c1);
            dataTable.Columns.Add(c2);
            dataTable.Columns.Add(c3);
            if (File.Exists(path))
            {
                var jsonString = File.ReadAllText(path);
                axisLineDrawDataGroupByDirs = JsonSerializer.Deserialize<Dictionary<DrawDirection, AxisLineDrawDataCollection>>(jsonString);
            }
            RefreshAxis();
            this.ListSpacing.Items.Clear();
            double spacing = 1200;
            for (int i = 0; i < 20; i++)
            {
                this.ListSpacing.Items.Add(spacing);
                spacing += 300;
            }
        }
        public bool IsActive => true;

        public Type WinType => this.GetType();

        private void button1_Click(object sender, EventArgs e)
        {
            GetCurrentDrawData().Clear();
            RefreshAxis();
        }
        /// <summary>
        /// 批量创建的轴网信息储存json,方便下次使用
        /// </summary>
        public void RefreshAxis()
        {
            initDataGridView();
            RefreshBox();
            this.axisDrawPenFrom1.RefreshAxis(double.Parse(this.textWidth.Text), double.Parse(this.textHeight.Text), axisLineDrawDataGroupByDirs);
            string jsonString = JsonSerializer.Serialize(axisLineDrawDataGroupByDirs);
            File.WriteAllText(path, jsonString);
        }
        private void axisDrawPenFrom1_Paint(object sender, PaintEventArgs e)
        {

        }
        Dictionary<DrawDirection, AxisLineDrawDataCollection> axisLineDrawDataGroupByDirs { get; set; }
        public string CurrentAction { get; set; }
        public LcAxisGrid lcAxisGrid { get; set; }
        public double Radius { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public string FirstAxisNum { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public string OrderingRule { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public string AxisNumType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        private void AxisManageFrom_Paint(object sender, PaintEventArgs e)
        {
            RefreshAxis();
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshAxis();
        }


        private void initDataGridView()
        {

            dataTable.Rows.Clear();
            if (this.rbTop.Checked)
            {
                foreach (var axisLineDrawData in axisLineDrawDataGroupByDirs[DrawDirection.Top])
                {
                    if (axisLineDrawData.Id == "1")
                    {
                        continue;
                    }
                    DataRow dr = dataTable.NewRow();
                    dr["Id"] = axisLineDrawData.Id;
                    dr["Spacing"] = axisLineDrawData.Spacing;
                    dr["Length"] = axisLineDrawData.Length;
                    dr["Count"] = axisLineDrawData.Count;
                    dataTable.Rows.Add(dr);
                }
            }
            else if (this.rbleft.Checked)
            {
                foreach (var axisLineDrawData in axisLineDrawDataGroupByDirs[DrawDirection.Left])
                {
                    if (axisLineDrawData.Id == "1")
                    {
                        continue;
                    }
                    DataRow dr = dataTable.NewRow();
                    dr["Id"] = axisLineDrawData.Id;
                    dr["Spacing"] = axisLineDrawData.Spacing;
                    dr["Length"] = axisLineDrawData.Length;
                    dr["Count"] = axisLineDrawData.Count;
                    dataTable.Rows.Add(dr);
                }
            }
            else if (this.rbBottom.Checked)
            {
                foreach (var axisLineDrawData in axisLineDrawDataGroupByDirs[DrawDirection.Bottom])
                {
                    if (axisLineDrawData.Id == "1")
                    {
                        continue;
                    }
                    DataRow dr = dataTable.NewRow();
                    dr["Id"] = axisLineDrawData.Id;
                    dr["Spacing"] = axisLineDrawData.Spacing;
                    dr["Length"] = axisLineDrawData.Length;
                    dr["Count"] = axisLineDrawData.Count;
                    dataTable.Rows.Add(dr);
                }
            }
            else if (this.rbRight.Checked)
            {
                foreach (var axisLineDrawData in axisLineDrawDataGroupByDirs[DrawDirection.Right])
                {
                    if (axisLineDrawData.Id == "1")
                    {
                        continue;
                    }
                    DataRow dr = dataTable.NewRow();
                    dr["Id"] = axisLineDrawData.Id;
                    dr["Spacing"] = axisLineDrawData.Spacing;
                    dr["Length"] = axisLineDrawData.Length;
                    dr["Count"] = axisLineDrawData.Count;
                    dataTable.Rows.Add(dr);
                }
            }
            this.dgvAxisLIneList.DataSource = dataTable;  //DataGridView绑定数据源
            //this.dgvAxisLIneList.AllowUserToAddRows = false;		//删除空行
        }
        private void rbTop_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbTop.Checked == true)
            {

                this.rbBottom.Checked = false;
                this.rbleft.Checked = false;
                this.rbRight.Checked = false;
                initDataGridView();
            }

        }

        private void rbBottom_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbBottom.Checked == true)
            {
                this.rbTop.Checked = false;
                this.rbleft.Checked = false;
                this.rbRight.Checked = false;

                initDataGridView();
            }

        }

        private void rbleft_CheckedChanged(object sender, EventArgs e)
        {

            if (this.rbleft.Checked == true)
            {
                this.rbTop.Checked = false;
                this.rbBottom.Checked = false;
                this.rbRight.Checked = false;
                initDataGridView();
            }
        }

        private void rbRight_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbRight.Checked == true)
            {
                this.rbTop.Checked = false;
                this.rbBottom.Checked = false;
                this.rbleft.Checked = false;
                initDataGridView();
            }
        }

        private void btnInsertAxisLine_Click(object sender, EventArgs e)
        {
            string jsonString = JsonSerializer.Serialize(axisLineDrawDataGroupByDirs);
            File.WriteAllText(path, jsonString);
            CovnentLcAxisGrid();
            this.CurrentAction = "InsertAxisGrid";
            this.DialogResult = DialogResult.OK;
            this.Close();
        }
        /// <summary>
        /// 批量创建轴网
        /// </summary>
        public void CovnentLcAxisGrid()
        {
            LcDocument doc = axisLineAction.LcDocument;
            lcAxisGrid = doc.CreateObject<LcAxisGrid>();
            lcAxisGrid.SumWidth = double.Parse(this.textWidth.Text) + LcAxisGrid.offValue * 2;
            lcAxisGrid.SumHeight = double.Parse(this.textHeight.Text) + LcAxisGrid.offValue * 2;
            foreach (var DrawDirectionGroup in axisLineDrawDataGroupByDirs)
            {
                switch (DrawDirectionGroup.Key)
                {
                    case DrawDirection.Top:
                        double lastSpacing = LcAxisGrid.offValue;
                        foreach (var axisLineDrawData in DrawDirectionGroup.Value)
                        {
                            var length = axisLineDrawData.Length < 0 ? lcAxisGrid.SumHeight : axisLineDrawData.Length + LcAxisGrid.offValue * 2;

                            for (int i = 0; i < axisLineDrawData.Count; i++)
                            {
                                lastSpacing += axisLineDrawData.Spacing;
                                LcAxisLine drawAxisLine = doc.CreateObject<LcAxisLine>();
                                LcLine lcLine = doc.CreateObject<LcLine>();
                                lcLine.Start = new Vector2(lastSpacing, lcAxisGrid.SumHeight);
                                lcLine.End = new Vector2(lastSpacing, lcAxisGrid.SumHeight - length);
                                lcLine.Color = ColorTranslator.ToHtml(System.Drawing.Color.Red);
                                drawAxisLine.AxisLine = lcLine;
                                lcAxisGrid.eleIds.Add(drawAxisLine.Id);
                                lcAxisGrid.InsertElement(drawAxisLine);
                            }
                        }
                        break;
                    case DrawDirection.Bottom:
                        lastSpacing = LcAxisGrid.offValue;
                        foreach (var axisLineDrawData in DrawDirectionGroup.Value)
                        {
                            var length = axisLineDrawData.Length < 0 ? lcAxisGrid.SumHeight : axisLineDrawData.Length + LcAxisGrid.offValue * 2;
                            for (int i = 0; i < axisLineDrawData.Count; i++)
                            {
                                lastSpacing += axisLineDrawData.Spacing;
                                LcAxisLine drawAxisLine = doc.CreateObject<LcAxisLine>();
                                LcLine lcLine = doc.CreateObject<LcLine>();
                                lcLine.Start = new Vector2(lastSpacing, 0);
                                lcLine.End = new Vector2(lastSpacing, length);
                                lcLine.Color = ColorTranslator.ToHtml(System.Drawing.Color.Red);
                                drawAxisLine.AxisLine = lcLine;
                                lcAxisGrid.eleIds.Add(drawAxisLine.Id);
                                lcAxisGrid.InsertElement(drawAxisLine);
                            }
                        }
                        break;
                    case DrawDirection.Left:
                        lastSpacing = LcAxisGrid.offValue;
                        foreach (var axisLineDrawData in DrawDirectionGroup.Value)
                        {
                            var length = axisLineDrawData.Length < 0 ? lcAxisGrid.SumWidth : axisLineDrawData.Length + LcAxisGrid.offValue * 2;

                            for (int i = 0; i < axisLineDrawData.Count; i++)
                            {
                                lastSpacing += axisLineDrawData.Spacing;
                                LcAxisLine drawAxisLine = doc.CreateObject<LcAxisLine>();
                                LcLine lcLine = doc.CreateObject<LcLine>();
                                lcLine.Start = new Vector2(0, lastSpacing);
                                lcLine.End = new Vector2(length, lastSpacing);
                                lcLine.Color = ColorTranslator.ToHtml(System.Drawing.Color.Red);
                                drawAxisLine.AxisLine = lcLine;
                                lcAxisGrid.eleIds.Add(drawAxisLine.Id);
                                lcAxisGrid.InsertElement(drawAxisLine);
                            }
                        }
                        break;
                    case DrawDirection.Right:
                        lastSpacing = LcAxisGrid.offValue;
                        foreach (var axisLineDrawData in DrawDirectionGroup.Value)
                        {
                            var length = axisLineDrawData.Length < 0 ? lcAxisGrid.SumWidth : axisLineDrawData.Length + LcAxisGrid.offValue * 2;

                            for (int i = 0; i < axisLineDrawData.Count; i++)
                            {
                                lastSpacing += axisLineDrawData.Spacing;
                                LcAxisLine drawAxisLine = doc.CreateObject<LcAxisLine>();
                                LcLine lcLine = doc.CreateObject<LcLine>();
                                lcLine.Start = new Vector2(lcAxisGrid.SumWidth, lastSpacing);
                                lcLine.End = new Vector2(lcAxisGrid.SumWidth - length, lastSpacing);
                                lcLine.Color = ColorTranslator.ToHtml(System.Drawing.Color.Red);
                                drawAxisLine.AxisLine = lcLine;
                                lcAxisGrid.eleIds.Add(drawAxisLine.Id);
                                lcAxisGrid.InsertElement(drawAxisLine);
                            }
                        }
                        break;
                    case DrawDirection.Angle:
                        break;
                    case DrawDirection.depth:
                        break;
                    default:
                        break;
                }

            }
        }
        /// <summary>
        /// 刷新轴网范围大小
        /// </summary>
        public void RefreshBox()
        {
            double boxWidth = 0;
            double boxHeight = 0;
            foreach (var dirGroupby in axisLineDrawDataGroupByDirs)
            {
                switch (dirGroupby.Key)
                {
                    case DrawDirection.Top:
                    case DrawDirection.Bottom:

                        double sumSpacing = 0;
                        foreach (AxisLineDrawData axisLineDraw in dirGroupby.Value)
                        {
                            sumSpacing += axisLineDraw.Spacing * axisLineDraw.Count;
                            if (axisLineDraw.Length > boxHeight)
                            {
                                boxHeight = axisLineDraw.Length;
                            }
                        }
                        if (sumSpacing > boxWidth)
                        {
                            boxWidth = sumSpacing;
                        }

                        break;
                    case DrawDirection.Left:
                    case DrawDirection.Right:
                        sumSpacing = 0;
                        foreach (AxisLineDrawData axisLineDraw in dirGroupby.Value)
                        {
                            sumSpacing += axisLineDraw.Spacing * axisLineDraw.Count;
                            if (axisLineDraw.Length > boxWidth)
                            {
                                boxWidth = axisLineDraw.Length;
                            }
                        }
                        if (sumSpacing > boxHeight)
                        {
                            boxHeight = sumSpacing;
                        }
                        break;
                    case DrawDirection.Angle:
                        break;
                    case DrawDirection.depth:
                        break;
                    default:
                        break;
                }
            }
            this.textWidth.Text = boxWidth.ToString();
            this.textHeight.Text = boxHeight.ToString();
        }
        /// <summary>
        /// 手动修改标格插入轴线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvAxisLIneList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            var row = this.dgvAxisLIneList.Rows[e.RowIndex];
            if (row.Cells["Id"].Value == null)
            {
                return;
            }
            AxisLineDrawDataCollection axisLineDrawDatas = GetCurrentDrawData();
            if (e.ColumnIndex == row.Cells["dgvSpacing"].ColumnIndex)
            {
                if (string.IsNullOrEmpty(row.Cells["dgvLength"].Value.ToString()))
                    row.Cells["dgvLength"].Value = -1;
                if (row.Cells["dgvCount"].Value == null || string.IsNullOrEmpty(row.Cells["dgvCount"].Value.ToString()))
                    row.Cells["dgvCount"].Value = 1;
            }
            else if (e.ColumnIndex == row.Cells["dgvLength"].ColumnIndex)
            {
                if (string.IsNullOrEmpty(row.Cells["dgvSpacing"].Value.ToString()))
                    row.Cells["dgvSpacing"].Value = 0;
                if (string.IsNullOrEmpty(row.Cells["dgvCount"].Value.ToString()))
                    row.Cells["dgvCount"].Value = 1;
            }
            else if (e.ColumnIndex == row.Cells["dgvCount"].ColumnIndex)
            {
                if (string.IsNullOrEmpty(row.Cells["dgvSpacing"].Value.ToString()))
                    row.Cells["dgvSpacing"].Value = 0;
                if (string.IsNullOrEmpty(row.Cells["dgvLength"].Value.ToString()))
                    row.Cells["dgvLength"].Value = -1;
            }
            if (!double.TryParse(row.Cells["dgvSpacing"].Value.ToString(), out double spacing) ||
               !double.TryParse(row.Cells["dgvLength"].Value.ToString(), out double length) ||
                !int.TryParse(row.Cells["dgvCount"].Value.ToString(), out int count))
            {
                return;
            }

            if (string.IsNullOrEmpty(row.Cells["Id"].Value.ToString()))
            {
                row.Cells["Id"].Value = Guid.NewGuid().ToString();
                dgvAxisLIneList.Columns["Id"].Visible = false;
                if (axisLineDrawDatas.Count == 0)
                {
                    AxisLineDrawData initial = new AxisLineDrawData();
                    initial.Id = "1";
                    initial.Spacing = 0;
                    initial.Length = -1;
                    initial.Count = 1;
                    axisLineDrawDatas.Add(initial);

                }
                AxisLineDrawData axisLineDrawData = new AxisLineDrawData();
                axisLineDrawData.Id = row.Cells["Id"].Value.ToString();
                axisLineDrawData.Spacing = spacing;
                axisLineDrawData.Length = length;
                axisLineDrawData.Count = count;
                axisLineDrawDatas.Add(axisLineDrawData);
            }
            else
            {
                var axisLineDrawData = axisLineDrawDatas.Where(x => x.Id == row.Cells["Id"].Value.ToString()).ToList().FirstOrDefault();
                axisLineDrawData.Spacing = spacing;
                axisLineDrawData.Length = length;
                axisLineDrawData.Count = count;
            }
            RefreshBox();
            this.axisDrawPenFrom1.RefreshAxis(double.Parse(this.textWidth.Text), double.Parse(this.textHeight.Text), axisLineDrawDataGroupByDirs);
        }

        /// <summary>
        /// 获取单选按钮更改后轴线的数据
        /// </summary>
        /// <returns></returns>
        public AxisLineDrawDataCollection GetCurrentDrawData()
        {
            AxisLineDrawDataCollection axisLineDrawDatas = null;
            if (this.rbTop.Checked)
            {
                axisLineDrawDatas = axisLineDrawDataGroupByDirs[DrawDirection.Top];
            }
            else if (this.rbBottom.Checked)
            {
                axisLineDrawDatas = axisLineDrawDataGroupByDirs[DrawDirection.Bottom];

            }
            else if (this.rbleft.Checked)
            {
                axisLineDrawDatas = axisLineDrawDataGroupByDirs[DrawDirection.Left];

            }
            else if (this.rbRight.Checked)
            {
                axisLineDrawDatas = axisLineDrawDataGroupByDirs[DrawDirection.Right];
            }
            return axisLineDrawDatas;
        }

        /// <summary>
        /// 插入固定距离的轴线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListSpacing_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            AxisLineDrawDataCollection axisLineDrawDatas = GetCurrentDrawData();
            if (axisLineDrawDatas.Count == 0)
            {
                AxisLineDrawData initial = new AxisLineDrawData();
                initial.Id = "1";
                initial.Spacing = 0;
                initial.Length = -1;
                initial.Count = 1;
                axisLineDrawDatas.Add(initial);

            }
            ListBox listBox = sender as ListBox;
            AxisLineDrawData axisLineDrawData = new AxisLineDrawData();
            axisLineDrawData.Id = Guid.NewGuid().ToString();
            axisLineDrawData.Spacing = (double)listBox.SelectedItem;
            axisLineDrawData.Length = -1;
            axisLineDrawData.Count = 1;
            axisLineDrawDatas.Add(axisLineDrawData);
            RefreshAxis();
        }
        /// <summary>
        /// 删除轴线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvAxisLIneList_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            AxisLineDrawDataCollection axisLineDrawDatas = GetCurrentDrawData();
            var row = e.Row;
            string id = row.Cells["Id"].Value.ToString();
            axisLineDrawDatas.Remove(id);
            RefreshBox();
            this.axisDrawPenFrom1.RefreshAxis(double.Parse(this.textWidth.Text), double.Parse(this.textHeight.Text), axisLineDrawDataGroupByDirs);
        }
    }
}
